﻿// See https://aka.ms/new-console-template for more information

using CO2NETSample;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.Json;
using Microsoft.Extensions.DependencyInjection;
using Senparc.CO2NET;
using Senparc.CO2NET.Extensions;
using Senparc.CO2NET.RegisterServices;
using System.ComponentModel.DataAnnotations;
using System.Net;
using System.Net.Mail;
using System.Net.WebSockets;
using System.Text;
using System.Web;

Console.WriteLine("Hello, Senparc!");

var configBuilder = new ConfigurationBuilder();
configBuilder.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true);

var config = configBuilder.Build();

var senparcSetting = new SenparcSetting();
config.GetSection("SenparcSetting").Bind(senparcSetting);

var services = new ServiceCollection();
services.AddMemoryCache();//添加内存缓存

//添加Senparc.CO2NET全局注册
services.AddSenparcGlobalServices(config);
Console.WriteLine("完成 CO2NET 全局注册");

//Start CO2NET
var register = RegisterService.Start(senparcSetting)
                              .UseSenparcGlobal();
register.ChangeDefaultCacheNamespace("SundaySharing");

var serviceProvider = services.BuildServiceProvider();

//HTTP 爬虫
//var url = "http://localhost:5172/";

//天气 GET 获取
var url = "http://www.weather.com.cn/data/cityinfo/101190408.html";
var weather = Senparc.CO2NET.HttpUtility.Get.GetJson<Weather>(serviceProvider, url/*, Encoding.UTF8, (r, d) =>
{
    Console.WriteLine(r);
    Console.WriteLine(d);
}*/);

Console.WriteLine("============");
Console.WriteLine($"城市：{weather.weatherinfo.city}");
Console.WriteLine($"城市ID：{weather.weatherinfo.cityid}");
Console.WriteLine($"温度：{weather.weatherinfo.temp1} ~ {weather.weatherinfo.temp2}");
Console.WriteLine($"天气：{weather.weatherinfo.weather}");

//获取文件
var imgUrl = "http://www.zhicheng.com/uploadfile/2019/0715/20190715034036304.jpg";
var imgResult = Senparc.CO2NET.HttpUtility.Get.Download(serviceProvider, imgUrl, Path.Combine(AppContext.BaseDirectory, "test.jpg"));
Console.WriteLine(imgResult);

var ms = new MemoryStream();
Senparc.CO2NET.HttpUtility.Get.Download(serviceProvider, imgUrl, ms);
ms.Seek(0, SeekOrigin.Begin);
var fs = new FileStream(Path.Combine(AppContext.BaseDirectory, "test2.jpg"), FileMode.Create);
ms.CopyTo(fs);
fs.Flush();
fs.Close();

Console.WriteLine("============");
Console.WriteLine("POST");

//Parallel.For(0, 1, async i =>
//{
var dt = SystemTime.Now;
//Form 表单提交
var formData = new Dictionary<string, string>() {
            { "code","20221127" }
        };

var cookieContainer = new CookieContainer();
var postResult = await Senparc.CO2NET.HttpUtility.RequestUtility.HttpPostAsync(serviceProvider, "http://localhost:5172/Home/PostParameter", cookieContainer, formData);

var cookieTime = cookieContainer.GetAllCookies()["Time"]?.Value;
var cookieTimeStr = cookieTime.UrlDecode();
Console.WriteLine("Time:" + cookieTimeStr);

Console.WriteLine(postResult);
//Console.WriteLine($"[{i.ToString("000")}]耗时：{SystemTime.DiffTotalMS(dt)}ms");
Console.WriteLine($"[]耗时：{SystemTime.DiffTotalMS(dt)}ms");
//});

//缓存
//添加缓存
var cache = Senparc.CO2NET.Cache
             .CacheStrategyFactory.GetObjectCacheStrategyInstance();
Console.WriteLine("当前使用缓存：" + cache.GetType().Name);

for (int i = 0; i < 10; i++)
{
    var cacheDt1 = SystemTime.Now;
    cache.Set("Time", "Memory - " + cookieTimeStr);
    var cacheDt2 = SystemTime.Now;

    var cacheTime = cache.Get("Time");
    var cacheDt3 = SystemTime.Now;

    Console.WriteLine("Cache Time: " + cacheTime);
    Console.WriteLine($"用时：Set:{(cacheDt2 - cacheDt1).TotalMilliseconds}ms，Get:{(cacheDt3 - cacheDt2).TotalMilliseconds}ms");
}

cache.Set("LocalTime", "Senparc - " + SystemTime.Now.ToString());

Console.WriteLine("\r\nRedis测试\r\n");

//启用Redis
var redisConStr = senparcSetting.Cache_Redis_Configuration;
Senparc.CO2NET.Cache.CsRedis.Register.SetConfigurationOption(redisConStr);//完成配置

//切换到Redis
Senparc.CO2NET.Cache.CsRedis.Register.UseKeyValueRedisNow();//启用Redis
//Senparc.CO2NET.Cache.CsRedis.Register.UseHashRedisNow();//启用Redis

cache = Senparc.CO2NET.Cache
             .CacheStrategyFactory.GetObjectCacheStrategyInstance();

Console.WriteLine("当前使用缓存：" + cache.GetType().Name);

for (int i = 0; i < 10; i++)
{
    var cacheDt1 = SystemTime.Now;
    cache.Set("Time", "Redis - " + cookieTimeStr);
    var cacheDt2 = SystemTime.Now;

    var cacheTime = cache.Get("Time");
    var cacheDt3 = SystemTime.Now;

    Console.WriteLine("Cache Time: " + cacheTime);
    Console.WriteLine($"用时：Set:{(cacheDt2 - cacheDt1).TotalMilliseconds}ms，Get:{(cacheDt3 - cacheDt2).TotalMilliseconds}ms");
}

//回到缓存策略
Senparc.CO2NET.Cache.CacheStrategyFactory.RegisterObjectCacheStrategy(() => Senparc.CO2NET.Cache.LocalObjectCacheStrategy.Instance);
cache = Senparc.CO2NET.Cache
             .CacheStrategyFactory.GetObjectCacheStrategyInstance();
Console.WriteLine("当前使用缓存：" + cache.GetType().Name);
Console.WriteLine($"LocalTime:{cache.Get("LocalTime")}");

var redisCache = Senparc.CO2NET.Cache.CsRedis.RedisObjectCacheStrategy.Instance;
Console.WriteLine($"Redis Time:{redisCache.Get("Time")}");


//储存和获取Json
await redisCache.SetAsync("Weather", weather, TimeSpan.FromMilliseconds(100 * 1000));
var weather2 = await redisCache.GetAsync<Weather>("Weather");
Console.WriteLine($"天气情况：{weather2.weatherinfo.weather.ToJson(true)}");

//使用Redis的Hash存储
Senparc.CO2NET.Cache.CsRedis.Register.UseHashRedisNow();
var redisHashCache = Senparc.CO2NET.Cache
             .CacheStrategyFactory.GetObjectCacheStrategyInstance();
redisHashCache.Set("WeatherHash", weather, TimeSpan.FromMilliseconds(100 * 1000));
redisHashCache.Set("WeatherHash2", weather, TimeSpan.FromMilliseconds(100 * 1000));

weather.weatherinfo.weather = "晴天";
redisHashCache.Set("WeatherHash2", weather, TimeSpan.FromMilliseconds(100 * 1000));

//缓存锁（分布式缓存锁）
var totalCount = 0;
Weather.Count = 0;
var lockDt = SystemTime.Now;
await redisCache.UpdateAsync("Count", 0);
var parallelResult = Parallel.For(0, 10, async i =>
{
    totalCount++;
    using (var redisLock = await redisCache.BeginCacheLockAsync("SundaySharing", "Wether"/*, 10, TimeSpan.FromSeconds(1)*/))
    {
        var count = await redisCache.GetAsync<int>("Count");
        count++;
        await redisCache.UpdateAsync("Count", count);
        //await Task.Delay(100);
    }
});

Console.WriteLine(parallelResult.ToJson(true));
Console.WriteLine("等待时间：" + SystemTime.DiffTotalMS(lockDt));

var finalCount = await redisCache.GetAsync("Count");
Console.WriteLine($"count:{finalCount}/{totalCount}");

Console.ReadKey();